/*
 * @Author: chenli chenli@kcwl.com
 * @Date: 2023-07-21 08:38:19
 * @LastEditors: chenli chenli@kcwl.com
 * @LastEditTime: 2023-07-21 10:59:09
 * @FilePath: \jsnode\typescript\generics\index.ts
 * @Description: 泛型学习
 */
{
  /** 一个泛型函数  ****************************************************/
  let getGenerics = <T>(val: T): T => {
    return val;
  };
  function identity<T>(arg: T): T {
    return arg;
  }
  let myIdentity: <T>(arg: T) => T = identity;
  console.log(
    getGenerics(2),
    getGenerics("zhangsan"),
    getGenerics(false),
    getGenerics(null)
  );
  console.log(myIdentity("zhang"));
  console.log(identity("zhang"));
  /** 泛型数组  ****************************************************/
  function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length); // Array has a .length, so no more error
    return arg;
  }
  loggingIdentity([1, 2, 34, 56, 3]);
  loggingIdentity(["22", "asdd", "2"]);

  //普通接口
  interface NormalAnimal {
    setData(name: string): string;
  }
  /** 泛型接口  ****************************************************/
  interface Animal {
    <T>(arg: T): T;
  }
  interface Car<T> {
    (arg: T): T;
  }
  let Cat: Animal = <T>(arg: T): T => {
    return arg;
  };
  function CarEX<T>(arg: T): T {
    return arg;
  }
  let Suv: Car<string> = CarEX;
  console.log(Cat("猫猫"));
  console.log(Suv("奔驰"));
  /** 泛型类  ****************************************************/
  class Ball<T> {
    box!: T;
    name: string;
  }
  let ball = new Ball<number>();
  ball.box = 1232;
  ball.name = "篮球";
  /** 泛型约束  ****************************************************/
  interface LimitLength {
    length: number;
  }
  //只有有length属性的才可以使用
  let getGenericsLength = <T extends LimitLength>(val: T): T => {
    console.log(val.length);
    return val;
  };
  /** 在泛型约束中使用类型参数  ****************************************************/
  function ObjKey<T,K extends keyof T>(obj: T, key: K) {
    return obj[key];
  }
  let x = { a: 1, b: 2, c: 3, d: 4 };
  console.log(ObjKey(x, "a"));
  /** 在泛型里使用类类型  ****************************************************/
  // TODO 学习泛型里使用类类型
}
